#include "SkillTornado.h"

#include "../Cats/CatsManager.h"
#include "../Cats/BaseCat.h"
#include "../Map/GameMap.h"

#include "../Supporting/SoundLoader.h"
#include "../Supporting/Enums/EnumSoundType.h"
#include "../Supporting/Enums/EnumSkillType.h"

using namespace cocos2d;

//===== CONSTRUCTOR =====
SkillTornado::SkillTornado() : BaseSkill()
{
	_skillType = SKILL_TORNADO;
	_skillDamage = 3;
	_chargePointRequired = 5;
	RECT_BUFFER_RADIUS = 10;

	skillEffectActivated = false;
}
//===== DESTRUCTOR ======
SkillTornado::~SkillTornado()
{
}

/*
 * @function: loadSkill
 * @param: filename of the skill button image to load
 * @brief: Create and load the skill as a CCSprite
 * @result: All required data loaded into memory
 */
BaseSkill* SkillTornado::loadSkill(cocos2d::CCString filename)
{
	SkillTornado *skill = new SkillTornado();

	if( skill && skill->initWithFile(filename.getCString()) )
	{
		skill->setColor(ccc3(100,100,100));
		skill->autorelease();
		return skill;
	}

	CC_SAFE_DELETE(skill);
	return NULL;
}

/*
 * @brief: Activate skill when user tap on the button. When this is enabled, the next touch will trigger the skill effect
 */
void SkillTornado::activateSkill()
{
	skillEffectActivated = true;
}

/*
 * @brief: Touch began funcion
 * @param location: location of the touch
 * @param mygamemanager: reference to GameManager
 * @return: true if this is a skill touch, else false
 */
bool SkillTornado::touchesBegan(cocos2d::CCPoint location, GameManager* mygamemanager)
{
	if( skillEffectActivated )
	{
		// Tornado Sound
		SoundLoader::playSound(SKILL_TORNADO_SOUND);

		//Get the y position to display the tornado
		int skilleffectposition = location.y;

		GameMap *myMap = GameMap::getInstance();
		int upperbound = myMap->getScreenTopBound()-(100*this->getScale());
		int lowerbound = myMap->getScreenBottomBound();

		//Capped it to the limits of the game screen
		if( location.y > upperbound )
			skilleffectposition = upperbound;
		else if( location.y < lowerbound )
			skilleffectposition = lowerbound;

		CCSize size = CCDirector::sharedDirector()->getWinSize();

		_skillEffectSprite = CCSprite::create();

		//========== ANIMATE IMAGE ==========
		CCAnimation *tornadoStartFrames = CCAnimation::create();
		CCAnimation *tornadoRunFrames = CCAnimation::create();
		//load the frames of animation
		for (int i = 0; i < 5; i++)
		{
			for( int j = 0 ; j < 2 ; j++ )
			{
				if( j == 0 && i > 2 )
					continue;
				CCSpriteFrame *frame = CCSpriteFrame::create("Game/Skill/[VFX] Tornado (256).png", CCRect((i * 256), j*256, 256, 256));

				if( j == 0 )
					tornadoStartFrames->addSpriteFrame(frame);
				else
					tornadoRunFrames->addSpriteFrame(frame);
			}
		}
		//setup animation properties
		tornadoStartFrames->setDelayPerUnit(0.1);
		tornadoStartFrames->setRestoreOriginalFrame(false);
		CCAnimate *tornadoStartAnimation = CCAnimate::create(tornadoStartFrames);

		tornadoRunFrames->setDelayPerUnit(0.1); // This animation contains 14 frames, will continuous 2.8 seconds.
		tornadoRunFrames->setLoops(10000);
		tornadoRunFrames->setRestoreOriginalFrame(true); // Return to the 1st frame after the 14th frame is played.
		CCAnimate *tornadoRunAnimation = CCAnimate::create(tornadoRunFrames);

		//start animating the running
		_skillEffectSprite->runAction(CCSequence::createWithTwoActions(tornadoStartAnimation,tornadoRunAnimation));
		_skillEffectSprite->setScale(this->getScale());
		_skillEffectSprite->setPosition(ccp(size.width-(80*this->getScale()),skilleffectposition+(140*this->getScale())));
		this->getParent()->addChild(_skillEffectSprite,7);

		skillEffectActivated = false;

		return true;
	}
	else
		BaseSkill::touchesBegan(location,mygamemanager);
}

/*
 * @function: update
 * @brief: update loop function of the game
 * @param timeDiff: time difference between this loop and previous loop in seconds
 * @param pCatsRef: reference to MyCatsManager
 * @param chargepoint: chargepoints of the user
 * @result: execute game logic for tornado skill
 */
void SkillTornado::update(float timeDiff, CatsManager* pCatsRef, int chargepoints)
{
	if( _skillEffectSprite )
	{
		_skillEffectSprite->setPosition(ccp(_skillEffectSprite->getPositionX()-4,_skillEffectSprite->getPositionY()));

		if( _skillEffectSprite->getPositionX() < -this->getContentSize().width )
		{
			// Stop sound here
			SoundLoader::endSound(SKILL_TORNADO_SOUND);

			_skillEffectSprite->removeFromParentAndCleanup(true);
			_skillEffectSprite = NULL;

			_isSkillActivated = false;
			//Restore button if these is sufficient charge points
			if( chargepoints >= _chargePointRequired )
				this->setColor(ccc3(255,255,255));

			return;
		}

		CCArray *_cats = pCatsRef->returnCats();
		for( int i = 0 ; i < _cats->count() ; i++ )
		{
			BaseCat *cat = (BaseCat*)_cats->objectAtIndex(i);

			if (cat == 0)
				continue;

			if(this->getSkillEffectRect().intersectsRect(cat->getRect()) )
			{
				cat->reduceHealth(_skillDamage, INJURY_WIND);
			}
		}
	}
}
